import os
import shutil
from typing import Dict, Any, List

from fastapi import APIRouter, HTTPException, UploadFile, File, Body, status, Path, Query

from config import FileHandle

router = APIRouter(prefix="/api/agents", tags=["agent"])

@router.get("/list", response_model=List[Dict[str, Any]])
def get_all_agents():
    """获取所有智能体列表"""
    print("获取所有智能体列表")
    return FileHandle.read_tools_config()


@router.get("/{agent_id}", response_model=Dict[str, Any])
def get_agent(agent_id: str):
    """获取指定ID的智能体"""
    agents = FileHandle.read_tools_config()
    for agent in agents:
        if agent.get('id') == agent_id:
            return agent
    raise HTTPException(status_code=404, detail=f"Agent with ID {agent_id} not found")


@router.post("/list", status_code=status.HTTP_201_CREATED, response_model=Dict[str, Any])
def create_agent(agent: Dict[str, Any] = Body(...)):
    """创建新的智能体"""
    agents = FileHandle.read_tools_config()

    # 检查ID是否已存在
    for existing_agent in agents:
        if existing_agent.get('id') == agent.get('id'):
            raise HTTPException(status_code=400, detail=f"Agent with ID {agent.get('id')} already exists")

    # 检查method文件是否存在，如果不存在，检查是否为上传的文件
    method_file = agent.get('method')
    method_file_path = os.path.join(FileHandle.TOOLS_DIR, method_file)

    if not os.path.exists(method_file_path):
        # 创建一个空文件，实际内容会通过上传功能添加
        with open(method_file_path, 'w', encoding='utf-8') as f:
            f.write(f"# {agent.get('description', 'Agent module')}\n\n")
            f.write("def invoke(message, tool, result_params):\n")
            f.write("    print(f\"Invoking {tool['name']}\")\n")
            f.write("    return f\"Successfully executed {tool['name']}\"\n")

    # 添加新智能体
    agents.append(agent)
    FileHandle.write_tools_config(agents)
    return agent


@router.put("/list/{agent_id}", response_model=Dict[str, Any])
def update_agent(agent_id: str = Path(..., description="Agent ID to update"), agent: Dict[str, Any] = Body(...)):
    """更新指定ID的智能体"""
    agents = FileHandle.read_tools_config()
    # 解析字符串形式的agent_id
    agent_id_parsed = None
    if agent_id.isdigit():
        agent_id_parsed = int(agent_id)
    elif '-' in agent_id and agent_id.split('-')[-1].isdigit():
        agent_id_parsed = int(agent_id.split('-')[-1])

    # 查找并更新智能体
    for i, existing_agent in enumerate(agents):
        if existing_agent.get('id') == agent_id_parsed or str(existing_agent.get('id')) == agent_id:
            # 检查method是否变更
            old_method = existing_agent.get('method')
            new_method = agent.get('method')

            if old_method != new_method:
                old_method_path = os.path.join(FileHandle.TOOLS_DIR, old_method)
                new_method_path = os.path.join(FileHandle.TOOLS_DIR, new_method)

                # 如果旧文件存在且新文件名不同，则重命名
                if os.path.exists(old_method_path) and old_method != new_method:
                    # 如果新文件已存在，则不覆盖，保留两者
                    if not os.path.exists(new_method_path):
                        shutil.copy2(old_method_path, new_method_path)

            # 更新智能体信息
            agents[i] = agent
            FileHandle.write_tools_config(agents)
            return agent

    raise HTTPException(status_code=404, detail=f"Agent with ID {agent_id} not found")


@router.delete("/list/{agent_id}/{delete_file}", status_code=status.HTTP_204_NO_CONTENT)
def delete_agent(
    agent_id: str = Path(..., description="Agent ID to delete"),
    delete_file: str = Path(..., description="Whether to delete the associated file")
):
    """删除指定ID的智能体"""
    try:
        agents = FileHandle.read_tools_config()
        
        # 尝试解析agent_id
        agent_id_parsed = None
        try:
            # 如果是纯数字
            if agent_id.isdigit():
                agent_id_parsed = int(agent_id)
            # 如果是形如"agent-4"的格式
            elif '-' in agent_id and agent_id.split('-')[-1].isdigit():
                agent_id_parsed = int(agent_id.split('-')[-1])
        except (ValueError, IndexError):
            pass  # 忽略解析错误

        # 将字符串形式的布尔值转换为实际布尔值（支持多种格式）
        delete_file_bool = delete_file.lower() in ["true", "yes", "1", "t", "y"]
        
        # 查找并删除智能体
        for i, agent in enumerate(agents):
            current_id = agent.get('id')
            # 尝试多种匹配方式
            if (current_id == agent_id or 
                current_id == agent_id_parsed or 
                str(current_id) == agent_id or
                (isinstance(current_id, int) and agent_id == f"agent-{current_id}")):
                
                # 如果指定删除文件，则同时删除method文件
                if delete_file_bool:
                    method_file = agent.get('method')
                    if method_file:
                        method_file_path = os.path.join(FileHandle.TOOLS_DIR, method_file)
                        if os.path.exists(method_file_path):
                            try:
                                os.remove(method_file_path)
                                print(f"Deleted file: {method_file_path}")
                            except Exception as e:
                                print(f"Error deleting file: {e}")

                # 从列表中删除智能体
                del agents[i]
                FileHandle.write_tools_config(agents)
                return
                
        # 如果没有找到匹配的智能体
        raise HTTPException(status_code=404, detail=f"Agent with ID {agent_id} not found")
        
    except Exception as e:
        # 记录并返回错误
        print(f"Error in delete_agent: {str(e)}")
        raise HTTPException(status_code=500, detail=f"Failed to delete agent: {str(e)}")


@router.post("/upload-agent-file", response_model=Dict[str, str])
async def upload_agent_file(file: UploadFile = File(...)):
    """上传智能体方法文件"""
    # 检查文件类型
    if not file.filename.endswith('.py'):
        raise HTTPException(status_code=400, detail="Only Python (.py) files are allowed")

    # 获取文件路径
    file_path = os.path.join(FileHandle.TOOLS_DIR, file.filename)

    try:
        # 读取并保存文件
        file_content = await file.read()
        with open(file_path, 'wb') as f:
            f.write(file_content)

        return {
            "filename": file.filename,
            "message": "File uploaded successfully"
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to upload file: {str(e)}")


@router.post("/check-method-exists", response_model=Dict[str, bool])
def check_method_exists(filename: str = Body(..., embed=True)):
    """检查方法文件是否存在"""
    file_path = os.path.join(FileHandle.TOOLS_DIR, filename)
    exists = os.path.exists(file_path)

    return {
        "exists": exists
    }


@router.get("/tools/commonTools", response_model=Dict[str, Any])
def get_unique_tools():
    """获取 AgentToolsConfig.json 中独有的工具数据"""
    try:
        # 读取两个配置文件
        tools_config = FileHandle.read_tools_config()
        common_tools = FileHandle.read_common_tools()

        # 获取 commonTools.json 中的工具 ID
        common_tool_ids = set()
        for tool_type in ['quickTools', 'MCPTools', 'workflowComponents']:
            for tool in common_tools.get(tool_type, []):
                common_tool_ids.add(tool.get('id'))

        # 找出 AgentToolsConfig.json 中独有的工具
        unique_tools = []
        for tool in tools_config:
            if tool.get('id') not in common_tool_ids:
                unique_tools.append(tool)

        return {
            "unique_tools": unique_tools,
            "total": len(unique_tools)
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/tools/commonTools/save", response_model=Dict[str, Any])
def save_agent_common_tools(tool: Dict[str, Any] = Body(...)):
    """保存工具到 CommonTools.json 文件"""
    try:
        # 读取现有的 CommonTools.json 文件
        common_tools = FileHandle.read_common_tools()
        
        # 获取 quickTools 数组，如果不存在则创建
        quick_tools = common_tools.get('quickTools', [])
        
        # 检查是否已存在相同 ID 的工具
        for existing_tool in quick_tools:
            if existing_tool.get('id') == tool.get('id'):
                raise HTTPException(
                    status_code=400,
                    detail=f"Tool with ID {tool.get('id')} already exists in CommonTools"
                )
        
        # 添加新工具到 quickTools 数组
        quick_tools.append(tool)
        common_tools['quickTools'] = quick_tools
        
        # 保存更新后的数据到文件
        FileHandle.write_common_tools(common_tools)
        
        return {
            "success": True,
            "message": "Tool saved successfully",
            "data": tool
        }
    except HTTPException as e:
        raise e
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Failed to save tool: {str(e)}"
        )